package com.xrui.hbase.util;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.net.URL;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.StringTokenizer;

/**
 * Utility for getting access to system resources.
 */
public final class Resources {
    private static final Logger LOG = LoggerFactory.getLogger(Resources.class);

    /**
     * Can not instantiate utility.
     */
    private Resources() {
    }

    /**
     * Returns the classloader to use. Currently this is this Thread's ContextClassLoader.
     *
     * @return The ClassLoader to use.
     */
    private static ClassLoader getClassLoader() {
        return Thread.currentThread().getContextClassLoader();
    }

    /**
     * Gets the named resource using the classloader, or null if it can not be found.
     *
     * @param resourceFileName The resource to load from the classpath.
     * @return The url of founded resource. If not found, returns null.
     */
    public static URL getResource(String resourceFileName) {
        URL resource = getClassLoader().getResource(resourceFileName);
        if (null == resource) {
            LOG.debug("Could not find resource: " + resourceFileName + ".  Is it on your classpath?");
            File fileInClassPath = searchFileInClassPath(resourceFileName);
            Path path = Paths.get(resourceFileName);
            if (fileInClassPath != null) {
                path = fileInClassPath.toPath();
            }

            try {
                resource = path.toUri().toURL();
            } catch (Exception ignore) {
            }
        }
        return resource;
    }

    /**
     * Search file in class path
     *
     * @param fileName file name
     * @return the searched file or null if not exists
     */
    public static File searchFileInClassPath(final String fileName) {
        final String classpathStr = System.getProperty("java.class.path");
        final String separator = System.getProperty("path.separator");
        final StringTokenizer strTokenizer = new StringTokenizer(classpathStr, separator);
        while (strTokenizer.hasMoreTokens()) {
            final String pathElement = strTokenizer.nextToken();
            final File directory = new File(pathElement);
            final File absoluteDirectory = directory
                .getAbsoluteFile();
            if (absoluteDirectory.isFile()) {
                final File target = new File(
                    absoluteDirectory.getParent(), fileName);
                if (target.exists()) {
                    return target;
                }
            } else {
                final File target = new File(directory, fileName);
                if (target.exists()) {
                    return target;
                }
            }
        }
        return null;
    }

    /**
     * Gets the named resource using the classloader, or null if it can not be found.
     * Clients should close streams returned by this method.
     *
     * @param resourceFileName The resource to load from the classpath.
     * @return The loaded resource as an InputStream.  If not found, returns null.
     */
    public static InputStream openSystemResource(String resourceFileName) {
        InputStream resource = getClassLoader().getResourceAsStream(resourceFileName);
        if (null == resource) {
            LOG.debug("Could not find resource: " + resourceFileName + ".  Is it on your classpath?");
        }
        return resource;
    }

    /**
     * Gets the named resource using the classloader, or null if it can not be found.
     * Clients should close streams returned by this method.
     *
     * @param resourceFileName The resource to load from the classpath.
     * @return The loaded resource as a BufferedReader.  If not found, returns null.
     */
    public static BufferedReader openSystemTextResource(String resourceFileName) {
        InputStream resource = getClassLoader().getResourceAsStream(resourceFileName);
        if (null == resource) {
            LOG.debug("Could not find resource: " + resourceFileName + ".  Is it on your classpath?");
            return null;
        }
        try {
            return new BufferedReader(new InputStreamReader(resource, "UTF-8"));
        } catch (UnsupportedEncodingException uee) {
            // Shouldn't create here; UTF-8 is a Java universal requirement.
            LOG.debug("Could not use UTF-8 charset to open this resource?");
            return null;
        }
    }
}
